package com.ceo.auth.jwt.chain;

import com.ceo.auth.jwt.handler.AbstractJwtHandler;
import com.ceo.auth.jwt.handler.JwtAuthenticationHandler;
import com.ceo.auth.jwt.handler.JwtPreAuthenticationHandler;
import com.ceo.auth.jwt.handler.JwtUserActionHandler;
import com.ceo.auth.jwt.wrapper.JwtWrapper;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

/**
 * @Create by hefy
 * @Date 2022/1/10 11:00
 */
@Component
public class DefaultJwtChain implements CallableChain<Boolean, JwtWrapper>, ApplicationContextAware, InitializingBean {

    private ApplicationContext applicationContext;

    private final List<AbstractJwtHandler> handlers = new ArrayList<>();

    @Override
    public Boolean doProceed(Supplier<JwtWrapper> supplier) throws Exception {
        int index = supplier.get().doNext();
        if (index >= handlers.size()) {
            return doProceed();
        } else {
            return handlers.get(index).doHandle(this, supplier);
        }
    }

    public Boolean doProceed() throws Exception {
        return Boolean.TRUE;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        initAuth();
    }

    private void registry(Class<? extends AbstractJwtHandler> clazz){
        handlers.add(applicationContext.getBean(clazz));
    }

    private void initAuth(){
        //身份验证(预处理)
        registry(JwtPreAuthenticationHandler.class);
        //身份验证
        registry(JwtAuthenticationHandler.class);
        //用户行为处理(当前用户参数注入)
        registry(JwtUserActionHandler.class);
        //权限验证(预处理)
//        registry(JwtPreAuthorizationHandler.class);
        //权限验证
//        registry(JwtAuthorizationHandler.class);
    }

}
